import asyncio
import logging

from aiogram import Bot, Dispatcher, Router, types
from aiogram.filters import Command, CommandStart, StateFilter, Text
from aiogram.types import Message
from brain import *
from aiogram.fsm.context import FSMContext
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.state import default_state

API_TOKEN = '6061245214:AAFHQoaJgDiWLOfUHxdwAxUlmI2cfv_LaNg'
knowledge_base: dict = load_knowledge_base('knowledge_base.json')

# All handlers should be attached to the Router (or Dispatcher)
dp = Dispatcher()


class MyStates(StatesGroup):
    question = State()
    answer = State()


new_question = ""


@dp.message(Command(commands=["start", "help"]), StateFilter(default_state))
async def start_handler(message: Message) -> None:
    """
    This handler receive messages with `/start` command
    """
    # Most event objects have aliases for API methods that can be called in events' context
    # For example if you want to answer to incoming message you can use `message.answer(...)` alias
    # and the target chat will be passed to :ref:`aiogram.methods.send_message.SendMessage`
    # method automatically or call API method directly via
    # Bot instance: `bot.send_message(chat_id=message.chat.id, ...)`
    await message.answer(f"Привет, {message.from_user.full_name}! Спроси у меня что-нибудь.")


@dp.message(StateFilter(default_state))
async def answer_hander(message: types.Message, state: FSMContext) -> None:
    user_input = message.text
    best_match: str | None = find_best_match(user_input, [q["question"] for q in knowledge_base["questions"]])
    if best_match:
        answer: str = get_answer_for_question(best_match, knowledge_base)
        await message.answer(answer)

    else:
        global new_question
        new_question = user_input
        await message.answer("Не знаю. Что я должен ответить?")
        await state.set_state(MyStates.question)


@dp.message(StateFilter(MyStates.question))
async def remember_answer_handler(message: types.Message, state: FSMContext) -> None:
    global new_question
    answer = message.text
    knowledge_base["questions"].append({"question": new_question, "answer": answer})
    save_knowledge_base('knowledge_base.json', knowledge_base)
    await message.answer("Спасибо, я запомнил.\nГотов отвечать на вопросы дальше.")
    await state.set_state(default_state)


async def main() -> None:
    # Initialize Bot instance with a default parse mode which will be passed to all API calls
    bot = Bot(API_TOKEN, parse_mode="HTML")
    # And the run events dispatching
    await dp.start_polling(bot)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    asyncio.run(main())
